home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / vs / vsem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  16.6 KB  |  629 lines

  1. #ifdef lint
  2. static char *SCCSid = "%W%    (NCSA)    %G%";
  3. #endif
  4.  
  5. /*
  6.  *
  7.  *      Virtual Screen Kernel Emulation Routines
  8.  *                      (vsem.c)
  9.  *  
  10.  *   National Center for Supercomputing Applications
  11.  *      by Gaige B. Paulsen
  12.  *
  13.  *    This file contains the private emulation calls for the NCSA
  14.  *  Virtual Screen Kernel.
  15.  *
  16.  *      Version Date    Notes
  17.  *      ------- ------  ---------------------------------------------------
  18.  *      0.01    861102  Initial coding -GBP
  19.  *      0.10    861111  Added/Modified VT emulator -GBP
  20.  *      0.50    861113  First compiled edition -GBP
  21.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  22.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  23.  */
  24.  
  25. #include <QuickDraw.h>
  26. #include <Controls.h>
  27.  
  28. #include "vsdata.h"
  29. #include "vskeys.h"
  30. #include "rsmac.h"
  31. #include "vsinterf.h"        /* BYU 2.4.18 */
  32. #include "vsintern.h"
  33.  
  34. void VSem
  35.   (
  36.      register unsigned char *c, /* pointer to character string */
  37.      register int ctr /* length of character string */
  38.   )
  39.   /* basic routine for placing characters on a virtual screen, and
  40.     interpreting control characters and escape sequences. Simple
  41.     interpretation of controls & escapes is done here, while the
  42.     harder stuff is done by calling VSIxx routines in vsintern.c. */
  43.   {
  44.     register int sx;
  45.     register int escflg; /* state of escape sequence interpretation */
  46.     int insert, attrib, extra, offend;
  47.     char *acurrent, *current, *start;
  48.  
  49.     escflg = VSIw->escflg;
  50.  
  51.     while (ctr > 0)
  52.       {
  53.         while ((escflg == 0) && (ctr > 0) && (*c < 32))
  54.           {
  55.             switch (*c)
  56.               {
  57.                 case 0x1b: /* esc */
  58.                     escflg++;
  59.                     break;
  60.                 case 0x0e: /* shift out */
  61.                     if (VSIw->G1)
  62.                         VSIw->attrib = VSgraph(VSIw->attrib);
  63.                     else
  64.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  65.                     VSIw->charset = 1;
  66.                     break;
  67.                 case 0x0f: /* shift in */
  68.                     if (VSIw->G0)
  69.                         VSIw->attrib = VSgraph(VSIw->attrib);
  70.                     else
  71.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  72.                     VSIw->charset = 0;
  73.                     break;
  74.                 case 0x07: /* bell */
  75.                     RSbell(VSIwn);
  76.                     break;
  77.                 case 0x08: /* backspace */
  78.                     VSIw->x--;
  79.                     if (VSIw->x < 0)
  80.                       /* hit left margin */
  81.                         VSIw->x = 0;
  82.                     break;
  83.                 case 0x0c: /* ff */
  84.                     VSIindex();
  85.                     break;
  86.                 case 0x09: /* ht */        /* Later change for versatile tabbing */
  87.                     VSItab();
  88.                     VScapture(c,1);                /* BYU 2.4.18 */
  89.                     break;
  90.                 case 0x0a: /* lf */
  91.                     VSIindex();
  92.                     break;
  93.                 case 0x0d: /* cr */
  94.                     VSIw->x = 0;
  95.                     VScapture(c,1);                /* BYU 2.4.18 */
  96.                     break;
  97.                 case 0x0b: /* vt */
  98.                     VSIindex();
  99.                     break;
  100. #ifdef CISB
  101.                 case 0x10: /* dle */
  102.                     bp_DLE(c, ctr);
  103.                     ctr = 0;
  104.                     break;
  105.                 case 0x05: /* enq */
  106.                     bp_ENQ();
  107.                     break;
  108. #endif CISB
  109.               } /* switch */
  110.             c++;
  111.             ctr--;
  112.           } /* while */
  113.         if ((escflg == 0) && (ctr > 0) && (*c & 0x80))    /* BYU 2.4.12 - VT220 starts here */
  114.           {                                                /* BYU 2.4.12 */
  115.             switch (*c)                                    /* BYU 2.4.12 */
  116.               {                                            /* BYU 2.4.12 */
  117.                 case 0x84: /* ind */            /* BYU 2.4.12 - same as ESC D */
  118.                     VSIindex();                    /* BYU 2.4.12 */
  119.                     goto ShortCut;                /* BYU 2.4.12 */
  120.                 case 0x85: /* nel */            /* BYU 2.4.12 - same as ESC E */
  121.                     VSIw->x = 0;                /* BYU 2.4.12 */
  122.                     VSIindex();                    /* BYU 2.4.12 */
  123.                     goto ShortCut;                /* BYU 2.4.12 */
  124.                 case 0x88: /* hts */            /* BYU 2.4.12 - same as ESC H */
  125.                     VSIw->tabs[VSIw->x] = 'x';    /* BYU 2.4.12 */
  126.                     goto ShortCut;                /* BYU 2.4.12 */
  127.                 case 0x8d: /* ri */                /* BYU 2.4.12 - same as ESC M */
  128.                     VSIrindex();                /* BYU 2.4.12 */
  129.                     goto ShortCut;                /* BYU 2.4.12 */
  130.                 case 0x9b: /* csi */            /* BYU 2.4.12 - same as ESC [ */
  131.                     VSIapclear();                /* BYU 2.4.12 */
  132.                     escflg = 2;                    /* BYU 2.4.12 */
  133.                     break;                        /* BYU 2.4.12 */
  134.                 case 0x86: /* ssa */            /* BYU 2.4.12 - same as ESC F */
  135.                 case 0x87: /* esa */            /* BYU 2.4.12 - same as ESC G */
  136.                 case 0x8e: /* ss2 */            /* BYU 2.4.12 - same as ESC N */
  137.                 case 0x8f: /* ss3 */            /* BYU 2.4.12 - same as ESC O */
  138.                 case 0x90: /* dcs */            /* BYU 2.4.12 - same as ESC P */
  139.                 case 0x93: /* sts */            /* BYU 2.4.12 - same as ESC S */
  140.                 case 0x96: /* spa */            /* BYU 2.4.12 - same as ESC V */
  141.                 case 0x97: /* epa */            /* BYU 2.4.12 - same as ESC W */
  142.                 case 0x9d: /* osc */            /* BYU 2.4.12 - same as ESC ] */
  143.                 case 0x9e: /* pm */                /* BYU 2.4.12 - same as ESC ^ */
  144.                 case 0x9f: /* apc */            /* BYU 2.4.12 - same as ESC _ */
  145.                     goto ShortCut;                /* BYU 2.4.12 */
  146.               } /* switch */                    /* BYU 2.4.12 */
  147.             c++;                                /* BYU 2.4.12 */
  148.             ctr--;                                /* BYU 2.4.12 */
  149.           } /* if */                            /* BYU 2.4.12 */
  150.         while ((ctr > 0) && (escflg == 0) && (*c >= 32))
  151.           {
  152.           /* display printing characters */
  153.             start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */
  154.             current = start; /* where to put next char */
  155.             acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; /* where to put corresponding attribute byte */
  156.             attrib = VSIw->attrib; /* current writing attribute */
  157.             insert = VSIw->IRM; /* insert mode (boolean) */
  158.             offend = 0; /* wrapped to next line (boolean) */
  159.             extra = 0; /* overwriting last character of line (boolean) */
  160.             sx = VSIw->x; /* starting column of area needing redrawing */
  161.             if (VSIw->x > VSIw->maxwidth)
  162.               {
  163.                 if (VSIw->DECAWM)
  164.                   {
  165.                   /* wrap to next line */
  166.                     VSIw->x = 0;
  167.                     VSIindex();
  168.                   }
  169.                 else
  170.                   /* stay at right margin */
  171.                     VSIw->x = VSIw->maxwidth;
  172.                 current = start = &VSIw->linest[VSIw->y]->text[VSIw->x];
  173.                 acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x];
  174.                 sx = VSIw->x;
  175.               } /* if */
  176.             while ((ctr > 0) && (*c >= 32) && (offend == 0))
  177.               {
  178.               /* write characters within a single line */
  179.                 if (insert)
  180.                   /* make room for the char */
  181.                     VSIinschar(1);
  182.               /* poke the character and its attribute into the
  183.                 screen buffer at the current cursor position */
  184.                 *current = *c;
  185.                 *acurrent = attrib;
  186.                 c++;
  187.                 ctr--;
  188.                 if (VSIw->x < VSIw->maxwidth)
  189.                   {
  190.                   /* advance the cursor position */
  191.                     acurrent++;
  192.                     current++;
  193.                     VSIw->x++;
  194.                   }
  195.                 else
  196.                   {
  197.                   /* hit right margin */
  198.                     if (VSIw->DECAWM)
  199.                       {
  200.                       /* autowrap to start of next line */
  201.                         VSIw->x++;
  202.                         offend = 1; /* terminate inner loop */
  203.                       }
  204.                     else
  205.                       {
  206.                       /* stay at right margin */
  207.                         VSIw->x = VSIw->maxwidth;
  208.                         extra = 1; /* cursor position doesn't advance */
  209.                       } /* if */
  210.                   } /* if */
  211.               } /* while */
  212.           /* update the screen to show what I've done */
  213.               extra += VSIw->x - sx + offend;                                    /* BYU 2.4.18 */
  214.             if (insert)
  215.                 VSIinsstring(extra, start);                                    /* BYU 2.4.18 */
  216.                                     /* actually just decides which RS to use */
  217.             else
  218.                 VSIdraw(VSIwn, sx, VSIw->y, VSIw->attrib, extra, start);    /* BYU 2.4.18 */
  219.             VScapture((unsigned char *) start, extra);                        /* BYU 2.4.18 */
  220.           } /* while */
  221.  
  222.         while((ctr > 0) && (escflg == 1))
  223.           { /* basic escape sequence processing */
  224.             switch (*c)
  225.               {
  226.                 case 0x08:
  227.                     VSIw->x--;
  228.                     if (VSIw->x < 0)
  229.                         VSIw->x = 0;
  230.                     break;
  231.                 case '[': /* csi */
  232.                     VSIapclear();
  233.                     escflg++;
  234.                     break;
  235.                 case '7':
  236.                     VSIsave();
  237.                     goto ShortCut;                /* BYU 2.4.12 */
  238.                 case '8':
  239.                     VSIrestore();
  240.                     goto ShortCut;                /* BYU 2.4.12 */
  241.                 case 'c':
  242.                     VSIreset();
  243.                     break;
  244.                 case 'D':
  245.                     VSIindex();
  246.                     goto ShortCut;                /* BYU 2.4.12 */
  247.                 case 'E':
  248.                     VSIw->x = 0;
  249.                     VSIindex();
  250.                     goto ShortCut;                /* BYU 2.4.12 */
  251.                 case 'M':
  252.                     VSIrindex();
  253.                     goto ShortCut;                /* BYU 2.4.12 */
  254.                 case '>':
  255.                     VSIw->DECPAM = 0;
  256.                     goto ShortCut;                /* BYU 2.4.12 */
  257.                 case '=':
  258.                     VSIw->DECPAM = 1;
  259.                     goto ShortCut;                /* BYU 2.4.12 */
  260.                 case 'Z':
  261.                     VTsendident();
  262.                     goto ShortCut;                /* BYU 2.4.12 */
  263.                 case ' ':                        /* BYU 2.4.12 */
  264.                 case '*':                        /* BYU 2.4.12 */
  265.                 case '#':
  266.                     escflg = 3;
  267.                     break;
  268.                 case '(':
  269.                     escflg = 4;
  270.                     break;
  271.                 case ')':
  272.                     escflg = 5;
  273.                     break;
  274.                 case 'H':
  275.                     VSIw->tabs[VSIw->x] = 'x';
  276.                     goto ShortCut;                /* BYU 2.4.12 */
  277. #ifdef CISB
  278.                 case 'I':
  279.                     bp_ESC_I();
  280.                     break;
  281. #endif CISB
  282.                 default:
  283.                     goto ShortCut;                /* BYU 2.4.12 */
  284.               } /* switch */
  285.             c++;
  286.             ctr--;
  287.           } /* while */
  288.         while ((escflg == 2) && (ctr > 0))
  289.           { /* "control sequence" processing */
  290.             switch (*c)
  291.               {
  292.                 case 0x08:
  293.                     VSIw->x--;
  294.                     if (VSIw->x < 0)
  295.                         VSIw->x = 0;
  296.                     break;
  297.                 case '0':
  298.                 case '1':
  299.                 case '2':
  300.                 case '3':
  301.                 case '4':
  302.                 case '5':
  303.                 case '6':
  304.                 case '7':
  305.                 case '8':
  306.                 case '9':
  307.                   /* parse numeric parameter */
  308.                     if (VSIw->parms[VSIw->parmptr] < 0)
  309.                         VSIw->parms[VSIw->parmptr] = 0;
  310.                     VSIw->parms[VSIw->parmptr] = VSIw->parms[VSIw->parmptr] * 10;
  311.                     VSIw->parms[VSIw->parmptr] += *c - '0';
  312.                     break;
  313.                 case '?':
  314.                   /* DEC-private control sequence */
  315.                     VSIw->parms[VSIw->parmptr++] = -2;
  316.                     break;
  317.                 case ';':
  318.                   /* parameter separator */
  319.                     VSIw->parmptr++;
  320.                     break;
  321.                 case 'A': /* cursor up */
  322. #if 1                                                        /* BYU */
  323.                     if (VSIw->parms[0]<1) VSIw->y--;        /* BYU */
  324.                     else VSIw->y-=VSIw->parms[0];            /* BYU */
  325.                     if ( VSIw->y < 0 ) VSIw->y=0;            /* BYU */
  326. #else                                                        /* BYU */
  327.                     if (VSIw->y < VSIw->top)
  328.                       {
  329.                       /* outside scrolling region */
  330.                         if (VSIw->parms[0] < 1)
  331.                             VSIw->y--;
  332.                         else
  333.                             VSIw->y -= VSIw->parms[0];
  334.                       }
  335.                     else
  336.                       {
  337.                       /* don't leave scrolling region */
  338.                         if (VSIw->parms[0] < 1)
  339.                             VSIw->y--;
  340.                         else
  341.                             VSIw->y -= VSIw->parms[0];
  342.                         if (VSIw->y < VSIw->top)
  343.                             VSIw->y = VSIw->top;
  344.                       }
  345. #endif                                                        /* BYU */
  346.                     VSIrange();
  347.                     goto ShortCut;                /* BYU 2.4.12 */
  348.                 case 'B': /* cursor down */
  349. #if 1                                                        /* BYU */
  350.                     if (VSIw->parms[0]<1) VSIw->y++;        /* BYU */
  351.                     else VSIw->y+=VSIw->parms[0];            /* BYU */
  352.                     if ( VSIw->y > VSIw->lines )             /* BYU */
  353.                         VSIw->y=VSIw->lines;                /* BYU */
  354. #else                                                        /* BYU */
  355.                     if (VSIw->y > VSIw->bottom)
  356.                       {
  357.                       /* outside scrolling region */
  358.                         if (VSIw->parms[0] < 1)
  359.                             VSIw->y++;
  360.                         else
  361.                             VSIw->y += VSIw->parms[0];
  362.                       }
  363.                     else
  364.                       {
  365.                       /* don't leave scrolling region */
  366.                         if (VSIw->parms[0] < 1)
  367.                             VSIw->y++;
  368.                         else
  369.                             VSIw->y += VSIw->parms[0];
  370.                         if (VSIw->y > VSIw->bottom)
  371.                             VSIw->y = VSIw->bottom;
  372.                       }
  373. #endif                                                        /* BYU */
  374.                     VSIrange();
  375.                     goto ShortCut;                /* BYU 2.4.12 */
  376.                 case 'C': /* cursor right */
  377.                     if (VSIw->parms[0] < 1)
  378.                         VSIw->x++;
  379.                     else
  380.                         VSIw->x += VSIw->parms[0];
  381.                     VSIrange();
  382.                     if (VSIw->x > VSIw->maxwidth)
  383.                         VSIw->x = VSIw->maxwidth;
  384.                     goto ShortCut;                /* BYU 2.4.12 */
  385.                 case 'D': /* cursor left */
  386.                     if (VSIw->parms[0] < 1)
  387.                         VSIw->x--;
  388.                     else
  389.                         VSIw->x -= VSIw->parms[0];
  390.                     VSIrange();
  391.                     goto ShortCut;                /* BYU 2.4.12 */
  392.                 case 'f':
  393.                 case 'H':
  394.                   /* absolute cursor positioning */
  395.                     VSIw->x = VSIw->parms[1] - 1;
  396.                     if (VSIw->DECORG)
  397.                       /* origin mode -- position relative to top of scrolling region */
  398.                         VSIw->y = VSIw->parms[0] - 1 + VSIw->top;
  399.                     else
  400.                         VSIw->y = VSIw->parms[0] - 1;
  401.                     VSIrange();
  402.                     goto ShortCut;                /* BYU 2.4.12 */
  403.                 case 'K':
  404.                   /* erase to beginning/end/whole of line */
  405.                     switch (VSIw->parms[0])
  406.                       {
  407.                         case -1:
  408.                         case  0:
  409.                             VSIeeol();
  410.                             break;
  411.                         case  1:
  412.                             VSIebol();
  413.                             break;
  414.                         case  2:
  415.                             VSIel(-1);
  416.                             break;
  417.                         default:
  418.                             goto ShortCut;        /* BYU 2.4.12 */
  419.                       } /* switch */
  420.                     goto ShortCut;                /* BYU 2.4.12 */
  421.                 case 'J':
  422.                   /* erase to beginning/end/whole of screen */
  423.                     switch (VSIw->parms[0])
  424.                       {
  425.                         case -1:
  426.                         case  0:
  427.                             VSIeeos();
  428.                             break;
  429.                         case  1:
  430.                             VSIebos();
  431.                             break;
  432.                         case  2:
  433.                             VSIes();
  434.                             break;
  435.                         default:
  436.                             goto ShortCut;        /* BYU 2.4.12 */
  437.                       } /* switch */
  438.                     goto ShortCut;                /* BYU 2.4.12 */
  439.                 case 'm':
  440.                   /* set/clear attributes */
  441.                   {
  442.                     int temp = 0;
  443.                     while (temp <= VSIw->parmptr)
  444.                          {
  445.                            if (VSIw->parms[temp] < 1)
  446.                             VSIw->attrib &= 128; /* turn them all off */
  447.                         else if (VSIw->parms[temp] > 20)
  448.           /* turn off the appropriate bit */
  449.                             VSIw->attrib &= ~(1 << (VSIw->parms[temp] - 21));
  450.                             else
  451.           /* turn on the appropriate bit */
  452.                         VSIw->attrib |= 1 << (VSIw->parms[temp] - 1);
  453.                         temp++;
  454.                       } /* while */
  455.                   }
  456.                     goto ShortCut;                /* BYU 2.4.12 */
  457.                 case 'q':
  458.                   /* flash dem LEDs. What LEDs? */
  459.                     goto ShortCut;                /* BYU 2.4.12 */
  460.                 case 'c':
  461.                     VTsendident();
  462.                     goto ShortCut;                /* BYU 2.4.12 */
  463.                 case 'n':
  464.                     switch (VSIw->parms[0])
  465.                       {
  466.                         case 5:
  467.                             VTsendstat();
  468.                             break;
  469.                         case 6:
  470.                             VTsendpos();
  471.                             break;
  472.                       } /* switch */
  473.                     goto ShortCut;                /* BYU 2.4.12 */
  474.                 case 'L':
  475.                     if (VSIw->parms[0] < 1)
  476.                         VSIw->parms[0] = 1;
  477.                     VSIinslines(VSIw->parms[0], -1);
  478.                     goto ShortCut;                /* BYU 2.4.12 */
  479.                 case 'M':
  480.                     if (VSIw->parms[0] < 1)
  481.                         VSIw->parms[0] = 1;
  482.                     VSIdellines(VSIw->parms[0], -1);
  483.                     goto ShortCut;                /* BYU 2.4.12 */
  484.                 case 'P':
  485.                     if (VSIw->parms[0] < 1)
  486.                         VSIw->parms[0] = 1;
  487.                     VSIdelchars(VSIw->parms[0]);
  488.                     goto ShortCut;                /* BYU 2.4.12 */
  489.                 case 'r':
  490.                   /* set scrolling region */
  491.                     if (VSIw->parms[0] < 0)
  492.                         VSIw->top = 0;
  493.                     else
  494.                         VSIw->top = VSIw->parms[0] - 1;
  495.                     if (VSIw->parms[1] < 0)
  496.                         VSIw->bottom = VSIw->lines;
  497.                     else
  498.                         VSIw->bottom = VSIw->parms[1] - 1;
  499.                     if (VSIw->top < 0)
  500.                         VSIw->top = 0;
  501.                     if (VSIw->top > VSIw->lines - 1)
  502.                         VSIw->top = VSIw->lines - 1;
  503.                     if (VSIw->bottom < 1)
  504.                         VSIw->bottom = VSIw->lines;
  505.                     if (VSIw->bottom > VSIw->lines)
  506.                         VSIw->bottom = VSIw->lines;
  507.                     VSIw->x = 0;
  508.                     VSIw->y = 0;
  509.                     if (VSIw->DECORG)
  510.                         VSIw->y = VSIw->top;    /* origin mode relative */
  511.                     goto ShortCut;                /* BYU 2.4.12 */
  512.                 case 'h':
  513.                   /* set options */
  514.                     VSIsetoption(1);
  515.                     goto ShortCut;                /* BYU 2.4.12 */
  516.                 case 'l':
  517.                   /* reset options */
  518.                     VSIsetoption(0);
  519.                     goto ShortCut;                /* BYU 2.4.12 */
  520.                 case 'g':
  521.                     if (VSIw->parms[0] == 3)
  522.                       /* clear all tabs */
  523.                         VSItabclear();
  524.                     else if (VSIw->parms[0] == 0 || VSIw->parms[0] < 0)
  525.                       /* clear tab at current position */
  526.                         VSIw->tabs[VSIw->x] = ' ';
  527.                     goto ShortCut;                /* BYU 2.4.12 */
  528.                 case '!':                        /* BYU 2.4.12 - More private DEC stuff? */
  529.                 case '\'':                        /* BYU 2.4.12 - More private DEC stuff? */
  530.                 case '\"':                        /* BYU 2.4.12 - More private DEC stuff? */
  531.                     escflg++;                    /* BYU 2.4.12 */
  532.                     break;                        /* BYU 2.4.12 */
  533.                 default:            /* Dang blasted strays... */
  534.                     goto ShortCut;                /* BYU 2.4.12 */
  535.               } /* switch */
  536.             c++;
  537.             ctr--;
  538.           } /* while */
  539.     
  540.         while ((escflg == 3) && (ctr > 0))
  541.           {    /* "#" handling */
  542.           /* no support for double-width and double-height characters yet */
  543.             switch (*c)
  544.               {
  545.                 case 0x08:
  546.                     VSIw->x--;
  547.                     if (VSIw->x < 0)
  548.                         VSIw->x = 0;
  549.                     break;
  550.                 case '8': /* alignment display */
  551.                     VTalign();
  552.                     goto ShortCut;                /* BYU 2.4.12 */
  553.                 default:
  554.                     goto ShortCut;                /* BYU 2.4.12 */
  555.               } /* switch */
  556.             c++;
  557.             ctr--;
  558.           } /* while */
  559.  
  560.         while ((escflg == 4) && (ctr > 0))
  561.           {    /* "(" handling (selection of G0 character set) */
  562.             switch (*c)
  563.               {
  564.                 case 0x08:
  565.                     VSIw->x--;
  566.                     if (VSIw->x < 0)
  567.                         VSIw->x = 0;
  568.                     break;
  569.                 case 'A': /* UK */
  570.                 case 'B': /* US */
  571.                 case '1': /* "soft" */
  572.                     VSIw->G0 = 0;
  573.                     if (!VSIw->charset)
  574.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  575.                     goto ShortCut;                /* BYU 2.4.12 */
  576.                 case '0': /* DEC special graphics */
  577.                 case '2': /* "soft" */
  578.                     VSIw->G0 = 1;
  579.                     if (!VSIw->charset)
  580.                         VSIw->attrib = VSgraph(VSIw->attrib);
  581.                     goto ShortCut;                /* BYU 2.4.12 */
  582.                 default:
  583.                     goto ShortCut;                /* BYU 2.4.12 */
  584.               } /* switch */
  585.             c++;
  586.             ctr--;
  587.           } /* while */
  588.     
  589.         while ((escflg == 5) && (ctr > 0))
  590.           {    /* ")" handling (selection of G1 character set) */
  591.             switch (*c)
  592.               {
  593.                 case 0x08:
  594.                     VSIw->x--;
  595.                     if (VSIw->x < 0)
  596.                         VSIw->x = 0;
  597.                     break;
  598.                 case 'A': /* UK */
  599.                 case 'B': /* US */
  600.                 case '1': /* "soft" */
  601.                     VSIw->G1 = 0;
  602.                     if (VSIw->charset)
  603.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  604.                     goto ShortCut;                /* BYU 2.4.12 */
  605.                 case '0': /* DEC special graphics */
  606.                 case '2': /* "soft" */
  607.                     VSIw->G1 = 1;
  608.                     if (VSIw->charset)
  609.                         VSIw->attrib = VSgraph(VSIw->attrib);
  610.                     goto ShortCut;                /* BYU 2.4.12 */
  611.                 default:
  612.                     goto ShortCut;                /* BYU 2.4.12 */
  613.               } /* switch */
  614.             c++;
  615.             ctr--;
  616.           } /* while */
  617.     
  618.         if ((escflg > 2) && (ctr > 0))
  619.           {
  620. ShortCut:                        /* BYU 2.4.12 - well, sacrificing style for speed */
  621.             escflg = 0;
  622.             c++;
  623.             ctr--;
  624.           } /* if */
  625.       } /* while (ctr > 0) */
  626.     VSIw->escflg = escflg;
  627.   } /* VSem */
  628.  
  629.